// Package util
// @Title util[简述该包的主要作用]
// @Description
// @Author  cnHuaShao
// @since v0.0.1
// @Version v1.0.0
// @Date 2024/4/21 21:51
// @Update 2024/4/21 21:51
package util

import (
	"github.com/google/uuid"
	"github.com/shopspring/decimal"
	"math/rand"
	"reflect"
	"strconv"
	"strings"
	"time"
	"unsafe"
)

const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"

var seededRand = rand.New(rand.NewSource(time.Now().UnixNano()))

// GenerateRandomString
// @Description: 生成随机字符串
// @param length
// @return string
func GenerateRandomString(length int) string {
	b := make([]byte, length)
	for i := range b {
		b[i] = charset[seededRand.Intn(len(charset))]
	}
	return string(b)
}

// GetBetweenStr
// @Description: 获取字符串之间的内容
// @param str 需要截取的字符串
// @param start 开始位置
// @param end 结束位置
func GetBetweenStr(str, start, end string) string {
	n := strings.Index(str, start)
	if n == -1 {
		n = 0
	}
	str = string([]byte(str)[n:])
	m := strings.Index(str, end)
	if m == -1 {
		m = len(str)
	}
	str = string([]byte(str)[:m])
	return str
}

// Substr
// @Description: 字符串从指定位置向下截取一定的长度字符串
// @param str 需要截取的字符串
// @param start 开始位置
// @param length 截取长度
func Substr(str string, start, length int) string {
	rs := []rune(str)
	rl := len(rs)
	end := 0

	if start < 0 {
		start = rl - 1 + start
	}
	end = start + length

	if start > end {
		start, end = end, start
	}

	if start < 0 {
		start = 0
	}
	if start > rl {
		start = rl
	}
	if end < 0 {
		end = 0
	}
	if end > rl {
		end = rl
	}

	return string(rs[start:end])
}

func BytesToString(b []byte) string {
	return *(*string)(unsafe.Pointer(&b))
}

func ContainsString(array []string, val string) (index int) {
	index = -1
	for i := 0; i < len(array); i++ {
		if array[i] == val {
			index = i
			return
		}
	}
	return
}

func String2Bytes(data string) []byte {
	sh := (*reflect.StringHeader)(unsafe.Pointer(&data))
	bh := reflect.SliceHeader{
		Data: sh.Data,
		Len:  sh.Len,
		Cap:  sh.Len,
	}
	return *(*[]byte)(unsafe.Pointer(&bh))
	// return []byte(data)
}

func IsNil(i interface{}) bool {
	/*vi := reflect.ValueOf(i)
	if vi.Kind() == reflect.Ptr {
		return vi.IsNil()
	}
	return false*/
	ret := i == nil

	if !ret { // 需要进一步做判断
		defer func() {
			recover()
		}()
		ret = reflect.ValueOf(i).IsNil() // 值类型做异常判断，会panic的
	}

	return ret
}

// ToInt string转int，忽略异常
func ToInt(s string) int {
	st, _ := strconv.Atoi(s)
	return st
}

// ToDecimal string转decimal，忽略异常
func ToDecimal(s string) decimal.Decimal {
	fs, err := decimal.NewFromString(s)
	if err != nil {
		return decimal.Decimal{}
	}
	return fs
}

func InterfaceToInt(s interface{}) int {
	return ToInt(s.(string))
}

// StringToBool :string to bool 接受 1, t, T, TRUE, true, True, 0, f, F, FALSE, false, False 等字符串；其他形式的字符串会返回错误
func StringToBool(s string) bool {
	b, _ := strconv.ParseBool(s)
	return b
}

// GetUUID
// @Description: 获取uuid
// @return string
// @return error
func GetUUID() string {
	return uuid.NewString()
}

// InterfaceToMapByReflection
// @Description: 将interface转换为map[string]interface{}
// @param v
// @return map[string]interface{}
func InterfaceToMapByReflection(v interface{}) map[string]interface{} {
	result := make(map[string]interface{})
	val := reflect.ValueOf(v)
	for i := 0; i < val.NumField(); i++ {
		fieldName := val.Type().Field(i).Name
		fieldValue := val.Field(i).Interface()
		result[fieldName] = fieldValue
	}
	return result
}
